package com.uex.dev.manage.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Preconditions;
import com.uex.dev.manage.admin.config.MiniserveConfig;
import com.uex.dev.manage.admin.dao.ProjectDao;
import com.uex.dev.manage.admin.dao.ProjectFilesDao;
import com.uex.dev.manage.admin.intercepter.OpenidContext;
import com.uex.dev.manage.admin.intercepter.UserContext;
import com.uex.dev.manage.admin.po.ProjectFilesPO;
import com.uex.dev.manage.admin.po.ProjectPO;
import com.uex.dev.manage.admin.po.UserPO;
import com.uex.dev.manage.admin.service.IProjectFilesService;
import com.uex.dev.manage.admin.utils.LogUtil;
import com.uex.dev.manage.admin.vo.project.ProjectFileResp;
import com.uex.dev.manage.admin.vo.wx.OpenidInfo;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wangchao
 * @since 2024-02-22
 */
@Slf4j
@Service
public class ProjectFilesServiceImpl extends ServiceImpl<ProjectFilesDao, ProjectFilesPO> implements IProjectFilesService {

    @Resource
    private ProjectDao projectDao;

    @Resource
    private MiniserveConfig miniserveConfig;

    @Override
    public List<ProjectFileResp> getProjectFiles(Integer prjId) {
        LambdaQueryWrapper<ProjectFilesPO> wrapper = Wrappers.<ProjectFilesPO>lambdaQuery()
                .eq(ProjectFilesPO::getFilePrjid, prjId);
        List<ProjectFilesPO> list = this.list(wrapper);
        ArrayList<ProjectFileResp> resultList = new ArrayList<>();
        list.forEach(projectFile -> {
            ProjectFileResp projectFileResp = ProjectFileResp.fromPO(projectFile);
            resultList.add(projectFileResp);
        });
        LogUtil.log(0, "查看项目文档");
        return resultList;
    }

    //TODO 不能改名字，改名字会重名导致无法更改
    @Override
    public Boolean addProjectFile(ProjectFilesPO projectAddFileReq) {
        Preconditions.checkArgument(ObjectUtils.isNotNull(projectAddFileReq.getFilePrjid()), "项目Id不能为空");
        Preconditions.checkArgument(StringUtils.isNotBlank(projectAddFileReq.getFileName()), "文件名称不能为空");
        Preconditions.checkArgument(StringUtils.isNotBlank(projectAddFileReq.getFileUrl()), "项目文件不能为空");
        LambdaQueryWrapper<ProjectPO> wrapper = Wrappers.<ProjectPO>lambdaQuery()
                .eq(ProjectPO::getPrjId, projectAddFileReq.getFilePrjid());
        Preconditions.checkArgument(ObjectUtils.isNotNull(projectDao.selectOne(wrapper)), "项目Id不存在");
        ProjectFilesPO prjFile = this.getOne(new LambdaQueryWrapper<ProjectFilesPO>()
                .eq(ProjectFilesPO::getFileName, projectAddFileReq.getFileName())
                .eq(ProjectFilesPO::getFilePrjid, projectAddFileReq.getFilePrjid()));
        Preconditions.checkArgument(Objects.isNull(prjFile), "文件名称已存在");
        // 拼接本地路径url
        String path = miniserveConfig.getFile().replace("{project}", projectAddFileReq.getFilePrjid().toString());
        String url = miniserveConfig.getPath() + path + projectAddFileReq.getFileUrl();

        // 判断文件是否存在
        File file = new File(url);
        Preconditions.checkArgument(file.exists(), "文件不存在");

        // 获取文件后缀
        String suffix = FilenameUtils.getExtension(file.getName());
        // 替换文件名
        String newFilePath = url.replace(file.getName(), UUID.randomUUID() + "." + suffix);
        File newFile = new File(newFilePath);
        file.renameTo(newFile);

        ProjectFilesPO projectFile = new ProjectFilesPO();
        BeanUtils.copyProperties(projectAddFileReq, projectFile);
        // 改回miniserve路径
        projectFile.setFileUrl(newFilePath.replace(miniserveConfig.getPath(), miniserveConfig.getUrl()));
        projectFile.setFileTime(LocalDateTime.now());
        // 添加当前用户
        UserPO user = UserContext.getUserInfoLocal();
        OpenidInfo openidInfo = OpenidContext.getOpenidLocal();
        projectFile.setFileUser(user != null ? user.getUserAccount() : openidInfo.getUserAccount());
        LogUtil.log(0, "添加项目文档");
        return this.save(projectFile);
    }

    @Override
    public void delProjectFile(Integer id) {
        ProjectFilesPO projectFile = this.getById(id);
        Preconditions.checkArgument(projectFile != null, "项目文档不存在");
        String fileUrl = projectFile.getFileUrl();
        String filePath = fileUrl.replace(miniserveConfig.getUrl(), miniserveConfig.getPath());
        // 创建一个File对象表示要删除的文件
        File file = new File(filePath);
        // 调用delete()方法删除文件
        boolean deleted = file.delete();
        if (!deleted) {
            log.error("[ProjectFile] Failed to delete the file {}", filePath);
        }
        this.removeById(id);
        LogUtil.log(0, "删除项目文档");
    }
}
